<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>The Default Constructible Type Requirement</title>
<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../../index.html" title="Chapter 1. Boost.Convert 2.0">
<link rel="up" href="../stream_converter.html" title="boost::cnv::stream Converter">
<link rel="prev" href="supported_string_types/custom_string_types.html" title="Custom String Types">
<link rel="next" href="../strtol_converter.html" title="boost::cnv::strtol Converter">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="spirit-nav">
<a accesskey="p" href="supported_string_types/custom_string_types.html"><img src="../../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../stream_converter.html"><img src="../../../images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../images/home.png" alt="Home"></a><a accesskey="n" href="../strtol_converter.html"><img src="../../../images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_convert.converters_detail.stream_converter.the___default_constructible__type_requirement"></a><a class="link" href="the___default_constructible__type_requirement.html" title="The Default Constructible Type Requirement">The
        <span class="emphasis"><em>Default Constructible</em></span> Type Requirement</a>
</h4></div></div></div>
<p>
          Due to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">stream</span></code> design it requires an <span class="emphasis"><em>initialized</em></span>
          temporary storage of <span class="emphasis"><em>TypeOut</em></span> type to put the result
          of the requested conversion to. Conceptually <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">cnv</span><span class="special">::</span><span class="identifier">cstream</span></code>
          achieves that with:
        </p>
<pre class="programlisting"><span class="identifier">istream_type</span><span class="special">&amp;</span> <span class="identifier">istream</span> <span class="special">=</span> <span class="identifier">stream_</span><span class="special">;</span>
<span class="identifier">TypeOut</span>        <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_default</span><span class="special">&lt;</span><span class="identifier">TypeOut</span><span class="special">&gt;();</span>

<span class="identifier">istream</span> <span class="special">&gt;&gt;</span> <span class="identifier">result</span><span class="special">;</span>
</pre>
<p>
          The temporary storage <code class="computeroutput"><span class="identifier">result</span></code>
          is initialized with <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_default</span><span class="special">()</span></code> the default implementation of which is
        </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span>
<span class="special">{</span>
   <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">make_default</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">T</span><span class="special">();</span> <span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
          Consequently,
        </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
            <span class="bold"><strong>By default</strong></span> the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">cnv</span><span class="special">::</span><span class="identifier">cstream</span></code>
            and <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">cnv</span><span class="special">::</span><span class="identifier">wstream</span></code> converters require the <span class="emphasis"><em>TypeOut</em></span>
            type to be <a href="http://en.cppreference.com/w/cpp/named_req/DefaultConstructible" target="_top"><span class="emphasis"><em>Default
            Constructible</em></span></a>.
          </p></td></tr>
</table></div>
<p>
          That said, a well-designed type (in my opinion, anyway) should only have
          meaningful and unambiguous constructors... and the default constructor
          is not always and necessarily one of them. Consider the following as one
          such example:
        </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">direction</span>
<span class="special">{</span>
    <span class="comment">// Note: the class does NOT have the default constructor.</span>

    <span class="keyword">enum</span> <span class="identifier">value_type</span> <span class="special">{</span> <span class="identifier">up</span><span class="special">,</span> <span class="identifier">dn</span> <span class="special">};</span>

    <span class="identifier">direction</span><span class="special">(</span><span class="identifier">value_type</span> <span class="identifier">value</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">value_</span><span class="special">(</span><span class="identifier">value</span><span class="special">)</span> <span class="special">{}</span>
    <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="identifier">direction</span> <span class="identifier">that</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">value_</span> <span class="special">==</span> <span class="identifier">that</span><span class="special">.</span><span class="identifier">value_</span><span class="special">;</span> <span class="special">}</span>
    <span class="identifier">value_type</span> <span class="identifier">value</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">value_</span><span class="special">;</span> <span class="special">}</span>

    <span class="keyword">private</span><span class="special">:</span> <span class="identifier">value_type</span> <span class="identifier">value_</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
        </p>
<p>
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&gt;&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span><span class="special">&amp;</span> <span class="identifier">stream</span><span class="special">,</span> <span class="identifier">direction</span><span class="special">&amp;</span> <span class="identifier">dir</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">str</span><span class="special">;</span> <span class="identifier">stream</span> <span class="special">&gt;&gt;</span> <span class="identifier">str</span><span class="special">;</span>

    <span class="comment">/**/</span> <span class="keyword">if</span> <span class="special">(</span><span class="identifier">str</span> <span class="special">==</span> <span class="string">"up"</span><span class="special">)</span> <span class="identifier">dir</span> <span class="special">=</span> <span class="identifier">direction</span><span class="special">::</span><span class="identifier">up</span><span class="special">;</span>
    <span class="keyword">else</span> <span class="keyword">if</span> <span class="special">(</span><span class="identifier">str</span> <span class="special">==</span> <span class="string">"dn"</span><span class="special">)</span> <span class="identifier">dir</span> <span class="special">=</span> <span class="identifier">direction</span><span class="special">::</span><span class="identifier">dn</span><span class="special">;</span>
    <span class="keyword">else</span> <span class="identifier">stream</span><span class="special">.</span><span class="identifier">setstate</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span><span class="special">::</span><span class="identifier">failbit</span><span class="special">);</span>

    <span class="keyword">return</span> <span class="identifier">stream</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">stream</span><span class="special">,</span> <span class="identifier">direction</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">dir</span><span class="special">)</span>
<span class="special">{</span>
    <span class="keyword">return</span> <span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">dir</span><span class="special">.</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">direction</span><span class="special">::</span><span class="identifier">up</span> <span class="special">?</span> <span class="string">"up"</span> <span class="special">:</span> <span class="string">"dn"</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
        </p>
<p>
          The <code class="computeroutput"><span class="identifier">direction</span></code> type has
          no default state. It is not <a href="http://en.cppreference.com/w/cpp/named_req/DefaultConstructible" target="_top"><span class="emphasis"><em>Default
          Constructible</em></span></a> and, consequently, the following does
          not compile:
        </p>
<pre class="programlisting"><span class="identifier">direction</span> <span class="identifier">dir1</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">&lt;</span><span class="identifier">direction</span><span class="special">&gt;(</span><span class="identifier">str</span><span class="special">,</span> <span class="identifier">cnv</span><span class="special">).</span><span class="identifier">value</span><span class="special">();</span> <span class="comment">// Does not compile</span>
<span class="identifier">direction</span> <span class="identifier">dir2</span> <span class="special">=</span> <span class="identifier">lexical_cast</span><span class="special">&lt;</span><span class="identifier">direction</span><span class="special">&gt;(</span><span class="identifier">str</span><span class="special">);</span>         <span class="comment">// Does not compile</span>
</pre>
<p>
          However, <span class="emphasis"><em>Boost.Convert</em></span> is able to handle such a type
          with little help from the user -- the instructions <span class="emphasis"><em>how</em></span>
          to create that mentioned temporary storage:
        </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span>
<span class="special">{</span>
    <span class="keyword">template</span><span class="special">&lt;&gt;</span> <span class="keyword">inline</span> <span class="identifier">direction</span> <span class="identifier">make_default</span><span class="special">&lt;</span><span class="identifier">direction</span><span class="special">&gt;()</span>
    <span class="special">{</span>
        <span class="keyword">return</span> <span class="identifier">direction</span><span class="special">(</span><span class="identifier">direction</span><span class="special">::</span><span class="identifier">up</span><span class="special">);</span>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
        </p>
<p>
          Now such class can be deployed with <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">cnv</span><span class="special">::</span><span class="identifier">cstream</span></code>:
        </p>
<pre class="programlisting"><span class="identifier">direction</span> <span class="identifier">dir1</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">&lt;</span><span class="identifier">direction</span><span class="special">&gt;(</span><span class="identifier">str</span><span class="special">,</span> <span class="identifier">cnv</span><span class="special">).</span><span class="identifier">value</span><span class="special">();</span> <span class="comment">// Compiles</span>
<span class="identifier">direction</span> <span class="identifier">dir2</span> <span class="special">=</span> <span class="identifier">lexical_cast</span><span class="special">&lt;</span><span class="identifier">direction</span><span class="special">&gt;(</span><span class="identifier">str</span><span class="special">);</span> <span class="comment">// Does not compile</span>
</pre>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2009-2022 Vladimir
      Batov<p>
        Distributed under the Boost Software License, Version 1.0. See copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>.
      </p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="supported_string_types/custom_string_types.html"><img src="../../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../stream_converter.html"><img src="../../../images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../images/home.png" alt="Home"></a><a accesskey="n" href="../strtol_converter.html"><img src="../../../images/next.png" alt="Next"></a>
</div>
</body>
</html>
